import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.Action;
import java.awt.geom.RoundRectangle2D;

//游戏主界面GUI类
//负责创建和展示游戏主界面，包含游戏地图、状态信息和操作控制

public class GameMainGUI {
    // 游戏主面板
    private JPanel gamePanel;
    // 分数显示标签
    private JLabel scoreLabel;
    // 耐久度显示标签
    private JLabel durabilityLabel;
    // 关卡等级显示标签
    private JLabel levelLabel;
    // 最高分显示标签
    private JLabel bestScoreLabel;

    // 游戏逻辑控制器
    private GameLogic gameLogic;
    // 返回菜单的事件监听器
    private ActionListener returnToMenuListener;

    //构造函数
    public GameMainGUI(GameLogic gameLogic, ActionListener returnToMenuListener) {
        this.gameLogic = gameLogic;
        this.returnToMenuListener = returnToMenuListener;
        createGamePanel(); // 初始化游戏面板
    }

    // 获取游戏主面板
    public JPanel getGamePanel() {
        return gamePanel;
    }

    // 更新游戏状态显示
    public void updateGameState() {
        GameState state = gameLogic.getState();
        scoreLabel.setText(String.valueOf(state.getScore()));
        durabilityLabel.setText(state.getDurability() + "/" + gameLogic.getRules().getStartDurability());
        levelLabel.setText(state.getLevel() + "/" + gameLogic.getRules().getMaxLevels());
        bestScoreLabel.setText(String.valueOf(state.getBestScore()));
    }

    //设置键盘按键绑定
    public void setupKeyBindings() {

        // 获取地图面板
        JPanel mapPanel = (JPanel)((JScrollPane)gamePanel.getComponent(1)).getViewport().getView();
        InputMap inputMap = mapPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = mapPanel.getActionMap();

        // 定义上移动作
        Action moveUpAction = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                handleMovement(0, -1);
            }
        };

        // 定义下移动作
        Action moveDownAction = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                handleMovement(0, 1);
            }
        };

        // 定义左移动作
        Action moveLeftAction = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                handleMovement(-1, 0);
            }
        };

        // 定义右移动作
        Action moveRightAction = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                handleMovement(1, 0);
            }
        };

        // 绑定上移按键（方向键上和W键）
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "moveUp");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "moveUp");
        actionMap.put("moveUp", moveUpAction);

        // 绑定下移按键（方向键下和S键）
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "moveDown");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "moveDown");
        actionMap.put("moveDown", moveDownAction);

        // 绑定左移按键（方向键左和A键）
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "moveLeft");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "moveLeft");
        actionMap.put("moveLeft", moveLeftAction);

        // 绑定右移按键（方向键右和D键）
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "moveRight");
        inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "moveRight");
        actionMap.put("moveRight", moveRightAction);
    }

    // 处理玩家移动
    private void handleMovement(int dx, int dy) {
        boolean moved = gameLogic.movePlayer(dx, dy);

        if (moved) {
            updateGameState(); // 更新游戏状态
            gamePanel.repaint(); // 重绘游戏面板

            // 检查游戏是否结束
            if (gameLogic.getState().isOver()) {
                showGameOver(); // 显示游戏结束对话框
            }
        }
    }

    //创建游戏主面板
    private void createGamePanel() {
        // 创建带有渐变背景的游戏主面板
        gamePanel = new JPanel(new BorderLayout()) {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                // 设置渐变背景
                GradientPaint gradient = new GradientPaint(0, 0, new Color(30, 30, 60),
                        getWidth(), getHeight(), new Color(10, 10, 30));
                g2d.setPaint(gradient);
                g2d.fillRect(0, 0, getWidth(), getHeight());
            }
        };

        // 创建信息面板（顶部）
        JPanel infoPanel = new JPanel(new GridLayout(1, 4));
        infoPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        infoPanel.setOpaque(false); // 透明背景

        // 初始化各种信息标签
        scoreLabel = createInfoLabel("0");
        durabilityLabel = createInfoLabel("100/100");
        levelLabel = createInfoLabel("1/10");
        bestScoreLabel = createInfoLabel(String.valueOf(gameLogic.getState().getBestScore()));

        // 将标签添加到信息面板
        infoPanel.add(createInfoPanel("当前分数", scoreLabel));
        infoPanel.add(createInfoPanel("耐久度", durabilityLabel));
        infoPanel.add(createInfoPanel("当前层数", levelLabel));
        infoPanel.add(createInfoPanel("最高分", bestScoreLabel));

        // 将信息面板添加到游戏主面板顶部
        gamePanel.add(infoPanel, BorderLayout.NORTH);

        // 创建地图面板
        JPanel mapPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (gameLogic != null) {
                    drawGame(g); // 绘制游戏地图
                }
            }
        };

        // 设置地图面板属性
        mapPanel.setPreferredSize(new Dimension(600, 600));
        mapPanel.setOpaque(false); // 透明背景
        mapPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); // 设置边距

        // 创建返回菜单按钮
        JButton backButton = createStyledButton("返回菜单");
        backButton.addActionListener(returnToMenuListener);

        // 创建底部面板
        JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        bottomPanel.setOpaque(false); // 透明背景
        bottomPanel.add(backButton);

        // 将地图面板放入滚动面板，添加到游戏中心区域
        gamePanel.add(new JScrollPane(mapPanel), BorderLayout.CENTER);
        // 添加底部面板
        gamePanel.add(bottomPanel, BorderLayout.SOUTH);

        // 设置地图面板可获取焦点
        mapPanel.setFocusable(true);
    }

    //创建信息标签
    private JLabel createInfoLabel(String text) {
        JLabel label = new JLabel(text, SwingConstants.CENTER);
        label.setFont(new Font("微软雅黑", Font.BOLD, 18));
        label.setForeground(Color.WHITE);
        return label;
    }

    //创建信息面板
    private JPanel createInfoPanel(String title, JLabel valueLabel) {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setOpaque(false); // 透明背景

        // 创建标题标签
        JLabel titleLabel = new JLabel(title, SwingConstants.CENTER);
        titleLabel.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        titleLabel.setForeground(new Color(200, 200, 200)); // 浅灰色

        // 设置值标签样式
        valueLabel.setFont(new Font("微软雅黑", Font.BOLD, 20));
        valueLabel.setForeground(new Color(255, 215, 0)); // 金色

        // 添加组件到面板
        panel.add(titleLabel, BorderLayout.NORTH);
        panel.add(valueLabel, BorderLayout.CENTER);

        return panel;
    }

    // 绘制游戏地图
    private void drawGame(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        // 开启抗锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 获取游戏地图和规则
        String[][] map = gameLogic.getMap();
        GameRules rules = gameLogic.getRules();

        // 计算合适的面板大小和单元格大小
        int panelSize = Math.min(gamePanel.getWidth() - 40, gamePanel.getHeight() - 100);
        int cellSize = panelSize / map.length;

        // 计算地图起始位置（居中显示）
        int startX = (gamePanel.getWidth() - (map.length * cellSize)) / 2;
        int startY = 50; // 顶部留出空间

        // 绘制地图背景（圆角矩形）
        g2d.setColor(new Color(40, 40, 80, 200));
        g2d.fillRoundRect(startX - 10, startY - 10,
                map.length * cellSize + 20, map.length * cellSize + 20, 20, 20);

        // 设置单元格字体
        Font cellFont = new Font("微软雅黑", Font.BOLD, (int)(cellSize * 0.5));
        g2d.setFont(cellFont);
        FontMetrics fm = g2d.getFontMetrics();

        // 绘制每个单元格
        for (int y = 0; y < map.length; y++) {
            for (int x = 0; x < map[y].length; x++) {
                String cell = map[y][x];
                Color color = rules.getColor(cell);

                // 绘制单元格背景（圆角矩形）
                g2d.setColor(color.darker().darker());
                g2d.fillRoundRect(startX + x * cellSize, startY + y * cellSize,
                        cellSize, cellSize, 10, 10);

                // 绘制单元格前景（稍小的圆角矩形）
                g2d.setColor(color);
                g2d.fillRoundRect(startX + x * cellSize + 2, startY + y * cellSize + 2,
                        cellSize - 4, cellSize - 4, 8, 8);

                // 绘制单元格内容（如果不是空格）
                if (!cell.equals(" ")) {
                    g2d.setColor(Color.BLACK);
                    int textX = startX + x * cellSize + (cellSize - fm.stringWidth(cell)) / 2;
                    int textY = startY + y * cellSize + ((cellSize - fm.getHeight()) / 2) + fm.getAscent();
                    g2d.drawString(cell, textX, textY);
                }
            }
        }
    }

    // 显示游戏结束对话框
    public void showGameOver() {
        // 创建游戏结束对话框
        JDialog gameOverDialog = new JDialog((Frame)SwingUtilities.getWindowAncestor(gamePanel), "游戏结束", true);
        gameOverDialog.setLayout(new BorderLayout());
        gameOverDialog.setSize(400, 250);
        gameOverDialog.setLocationRelativeTo(gamePanel); // 居中显示

        // 创建消息标签
        JLabel messageLabel = new JLabel(
                "<html><center><h1>游戏结束！</h1>" +
                        "<p>你的分数是: " + gameLogic.getState().getScore() + "</p>" +
                        "<p>最高分: " + gameLogic.getState().getBestScore() + "</p></center></html>",
                SwingConstants.CENTER);
        messageLabel.setFont(new Font("微软雅黑", Font.PLAIN, 16));

        // 创建按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout());
        JButton restartButton = createStyledButton("重新开始");
        JButton menuButton = createStyledButton("返回菜单");

        // 设置重新开始按钮事件
        restartButton.addActionListener(e -> {
            gameLogic = new GameLogic(gameLogic.getState().getBestScore());
            updateGameState();
            gameOverDialog.dispose();
            gamePanel.repaint();
            gamePanel.requestFocusInWindow();
        });

        // 设置返回菜单按钮事件
        menuButton.addActionListener(e -> {
            gameOverDialog.dispose();
            returnToMenuListener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ""));
        });

        // 添加按钮到按钮面板
        buttonPanel.add(restartButton);
        buttonPanel.add(menuButton);

        // 添加组件到对话框
        gameOverDialog.add(messageLabel, BorderLayout.CENTER);
        gameOverDialog.add(buttonPanel, BorderLayout.SOUTH);
        gameOverDialog.setVisible(true);
    }

    //创建样式化按钮
    private JButton createStyledButton(String text) {
        // 自定义按钮绘制
        JButton button = new JButton(text) {
            @Override
            protected void paintComponent(Graphics g) {
                Graphics2D g2 = (Graphics2D) g;
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                // 根据按钮状态设置不同颜色
                if (getModel().isPressed()) {
                    g2.setColor(new Color(100, 100, 150)); // 按下状态
                } else if (getModel().isRollover()) {
                    g2.setColor(new Color(80, 80, 130)); // 悬停状态
                } else {
                    g2.setColor(new Color(60, 60, 100)); // 正常状态
                }

                // 绘制圆角矩形背景
                g2.fill(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 20, 20));
                g2.setColor(Color.WHITE);
                g2.setFont(new Font("微软雅黑", Font.BOLD, 18));
                // 居中绘制文本
                FontMetrics fm = g2.getFontMetrics();
                int x = (getWidth() - fm.stringWidth(getText())) / 2;
                int y = (getHeight() - fm.getHeight()) / 2 + fm.getAscent();
                g2.drawString(getText(), x, y);
            }
        };

        // 设置按钮属性
        button.setContentAreaFilled(false);
        button.setBorderPainted(false);
        button.setFocusPainted(false);
        button.setPreferredSize(new Dimension(200, 50));
        return button;
    }
}